#define NOMINMAX
#include "FI_CIBRepoData.h"
#include <bondlib/BondCalendar.h>
#include <core/time/time.h>
#include <msgcenter/FIMsgProcess.h>
#include <qbkernel/include/qb_base.h>
#include <qbprotocol/include/rdProto.h>
#include <qbprotocol/include/SSFIModel.h>
#include <qbtools/message/MessagePoster.h>
#include <uam/ServerTimeMgr.h>

void FICIBRepoData::iCache::clear()
{
	m_tLastUpdateTime = 0;
	m_strUpdateTime.clear();
	m_vctOrder.clear();
	m_mapData.clear();
}

void FICIBRepoData::iCache::initial()
{
	m_vctOrder = { "DR001", "DR007", "DR014", "DR021", "DR1M", "DR2M" };

	m_mapData.insert({ "DR001", xQbCibRepo_c("DR001", 0.0000, 0.0000, 0) });
	m_mapData.insert({ "DR007", xQbCibRepo_c("DR007", 0.0000, 0.0000, 0) });
	m_mapData.insert({ "DR014", xQbCibRepo_c("DR014", 0.0000, 0.0000, 0) });
	m_mapData.insert({ "DR021", xQbCibRepo_c("DR021", 0.0000, 0.0000, 0) });
	m_mapData.insert({ "DR1M", xQbCibRepo_c("DR1M", 0.0000, 0.0000, 0) });
	m_mapData.insert({ "DR2M", xQbCibRepo_c("DR2M", 0.0000, 0.0000, 0) });
}

bool FICIBRepoData::iCache::update(xQbCibRepoAck_c* pdata)
{
	bool bRet = false;

	for (auto itr = pdata->m_List.begin();
		itr != pdata->m_List.end(); ++itr)
	{
		MAP_DATA::iterator itrFind = m_mapData.find(itr->m_szID);
		if (itrFind != m_mapData.end())
		{
			xQbCibRepo_c& xcrl = itrFind->second;

			const xQbCibRepo_c& xcrr = *itr;

			if (xcrr.m_tUpdateTime >= xcrl.m_tUpdateTime)
			{
				bRet = true;
				xcrl = xcrr;

				m_tLastUpdateTime = std::max(m_tLastUpdateTime, xcrr.m_tUpdateTime);

				if (m_tLastUpdateTime != 0)
				{
					tm stTm = qb::base::time2tm(m_tLastUpdateTime);
					m_strUpdateTime = QString::asprintf("%02d:%02d:%02d", stTm.tm_hour, stTm.tm_min, stTm.tm_sec);
				}
			}
		}
	}

	return bRet;
}

FICIBRepoData::FICIBRepoData()
{
	m_iCache.clear();
	m_iCache.initial();
}

void FICIBRepoData::clear()
{
	SCOPED_MUTEX(m_lock);
	m_iCache.clear();
	m_iCache.initial();
}

FICIBRepoData::MAP_DATA& FICIBRepoData::getData()
{
	return m_iCache.m_mapData;
}

FICIBRepoData::VCT_IDS& FICIBRepoData::getOrder()
{
	return m_iCache.m_vctOrder;
}

QString FICIBRepoData::getLastUpdate() const
{
	return m_iCache.m_strUpdateTime;
}

void FICIBRepoData::reqData(MessageReceiver* msgRecv)
{
	static bool reqOnce = false;
	if (reqOnce)return;
	reqOnce = true;

	//取最近工作日
	time_t tToday = ServerTimeMgr::instance().serverTime() + 60 * 60 * 24;
	CBondCalendar::GetPreTradingDay(tToday, false);
	tm tmToday = qb::base::time2tm(tToday);

	m_req.m_Date = (tmToday.tm_year + 1900) * 10000 + (tmToday.tm_mon + 1) * 100 + tmToday.tm_mday;

	qb::SSRequestMsg msg;
	msg.m_pRequest = &m_req;
	msg.m_FuncID = E_FID_CIB_REPO_REQ;
	MessagePoster poster(&msg, qbmsg::fixedincome::EncodeFunc);
	poster.send(msgRecv);
}

bool FICIBRepoData::onReceive(int32_t funcId, const qb::SSAckMsg& msg)
{
	if (funcId != E_FID_CIB_REPO_REQ && funcId != E_FID_CIB_REPO_PUSH)return false;

	xQbCibRepoAck_c* pdata = (xQbCibRepoAck_c*)msg.m_pRet;
	if (!pdata)return false;

	SCOPED_MUTEX(m_lock);
	if (m_iCache.update(pdata))return true;

	return false;
}
